%%%%%%%%%%%%%%%%%%%%%%%
%%
%% Module summary
%%
%% Main authors: 
%% Progress to usefulness: 
%%
%% Server for ordinary clients. 
%% Uses a binary protocol with message headers. 
%%
%%%%%%%%%%%%%%%%%%%%%%%

-module(client_server).
-behaviour(gen_server).
-include("db.hrl").

-export([start_link/0,start_link/1]).
-export([init/1, handle_call/3,handle_cast/2,handle_info/2
        ,code_change/3,terminate/2]).

start_link() ->
    io:format("Loading Client Server Module\n"),
    spawn_link(fun () -> start() end),
    undefined.

start_link(_Args) ->
    io:format("Loading Client Server Module\n"),
    spawn_link(fun () -> start() end),
    undefined.

init(_Args) ->
    undefined.

handle_call(_Msg, _From, _State) ->
    undefined.

handle_cast(_Request, _State) ->
    undefined.

handle_info(_Info, _State) ->
    undefined.

code_change(_OldVsn, _State, _Extra) ->
    undefined.

%
% Function called when terminated
%
terminate(_Reason,_State) ->
    io:format("Terminating Client Server module~n").

% Create a port in which to listen for connecting users
start() ->
   PublicSocket = networking:start(),
   server_loop(PublicSocket).

%% Keep listening to connecting users
server_loop(PublicSocket) ->
   PrivSocket = networking:accept(PublicSocket),
   spawn(fun() -> handle_choice(PrivSocket) end ),
   io:fwrite("new user connected"),
   server_loop(PublicSocket).

%% a "main menu" in which connecting users
%% enter what they want do put/get
handle_choice(Socket) ->
   { Code, Key, Value } = clientiface:get_message(Socket),
   handle_message(Code, Key, Value).

%% receives a key and a value, sends OK
handle_message("PUT", Key, Value) ->
   io:fwrite("Store the key and value" ++ Key ++ ":" ++ Value),
   node:put(Key, Value),
   clientiface:reply_put_ok(Key, ""),
   ok;

%% receives a key and returns a value
handle_message("GET", Key, _Value) ->
   io:fwrite("got key, time to return value:" ++ Key),
   StoredValue = node:get(Key),
   clientiface:reply_get_ok(Key, StoredValue),
   ok;

handle_message("DEL", Key, _Value) ->
   io:fwrite("got key, time to remove the pair:" ++ Key),
   node:remove(Key),
   clientiface:reply_del_ok(Key, ""),
   ok;

handle_message(Msg, _Key, _Value) ->
   io:fwrite("Received unsupported message: " ++ Msg),
   ok.


